"""
语音参数控制器
提供语音参数调节功能
"""

import math
from typing import Dict, Any, Optional
from dataclasses import dataclass


@dataclass
class VoiceSettings:
    """语音设置"""
    rate: int = 200  # 语速 (50-500)
    volume: float = 0.9  # 音量 (0.0-1.0)
    pitch: int = 50  # 音调 (0-100)
    emphasis: float = 1.0  # 重音强度 (0.5-2.0)
    pause_duration: float = 0.5  # 停顿时长 (秒)
    breathing: bool = False  # 是否添加呼吸声
    gender_factor: float = 1.0  # 性别因子 (0.5-2.0, <1.0偏女性, >1.0偏男性)


class VoiceController:
    """语音控制器"""
    
    def __init__(self):
        self.settings = VoiceSettings()
        self._presets = {
            'normal': VoiceSettings(rate=200, volume=0.9, pitch=50),
            'slow': VoiceSettings(rate=120, volume=0.95, pitch=45),
            'fast': VoiceSettings(rate=300, volume=0.85, pitch=55),
            'calm': VoiceSettings(rate=150, volume=0.8, pitch=40, emphasis=0.8),
            'energetic': VoiceSettings(rate=250, volume=1.0, pitch=60, emphasis=1.3),
            'robot': VoiceSettings(rate=180, volume=0.7, pitch=30, emphasis=0.5),
            'child': VoiceSettings(rate=220, volume=0.85, pitch=70, gender_factor=0.7),
            'elderly': VoiceSettings(rate=130, volume=0.8, pitch=35, emphasis=0.9),
            'news_anchor': VoiceSettings(rate=160, volume=0.9, pitch=50, emphasis=1.1),
            'storyteller': VoiceSettings(rate=140, volume=0.85, pitch=45, emphasis=1.2, breathing=True)
        }
    
    def apply_preset(self, preset_name: str) -> bool:
        """应用预设"""
        if preset_name in self._presets:
            self.settings = self._presets[preset_name]
            return True
        return False
    
    def get_presets(self) -> Dict[str, VoiceSettings]:
        """获取所有预设"""
        return self._presets.copy()
    
    def update_settings(self, **kwargs) -> bool:
        """更新设置"""
        try:
            for key, value in kwargs.items():
                if hasattr(self.settings, key):
                    setattr(self.settings, key, value)
            return self._validate_settings()
        except Exception:
            return False
    
    def _validate_settings(self) -> bool:
        """验证设置的有效性"""
        settings = self.settings
        
        if not (50 <= settings.rate <= 500):
            return False
        
        if not (0.0 <= settings.volume <= 1.0):
            return False
        
        if not (0 <= settings.pitch <= 100):
            return False
        
        if not (0.5 <= settings.emphasis <= 2.0):
            return False
        
        if settings.pause_duration < 0:
            return False
        
        if not (0.5 <= settings.gender_factor <= 2.0):
            return False
        
        return True
    
    def get_engine_settings(self, engine_type: str = 'pyttsx3') -> Dict[str, Any]:
        """获取引擎特定设置"""
        if engine_type == 'pyttsx3':
            return {
                'rate': self.settings.rate,
                'volume': self.settings.volume
            }
        elif engine_type == 'espeak':
            return {
                'speed': int(self.settings.rate * 1.5),
                'volume': int(self.settings.volume * 100),
                'pitch': self.settings.pitch,
                'wordgap': int(self.settings.pause_duration * 10)
            }
        else:
            return {}
    
    def process_text(self, text: str) -> str:
        """处理文本，添加停顿和重音标记"""
        processed_text = text
        
        # 添加段落间停顿
        processed_text = self._add_paragraph_pauses(processed_text)
        
        # 添加重音标记
        if self.settings.emphasis != 1.0:
            processed_text = self._add_emphasis(processed_text)
        
        # 添加呼吸停顿
        if self.settings.breathing:
            processed_text = self._add_breathing_pauses(processed_text)
        
        return processed_text
    
    def _add_paragraph_pauses(self, text: str) -> str:
        """添加段落间停顿"""
        # 在句号后添加适当停顿
        text = text.replace('。', f'。 <break time="{self.settings.pause_duration}s"/>')
        text = text.replace('.', f'. <break time="{self.settings.pause_duration}s"/>')
        text = text.replace('！', f'！ <break time="{self.settings.pause_duration * 1.2}s"/>')
        text = text.replace('!', f'! <break time="{self.settings.pause_duration * 1.2}s"/>')
        text = text.replace('？', f'？ <break time="{self.settings.pause_duration}s"/>')
        text = text.replace('?', f'? <break time="{self.settings.pause_duration}s"/>')
        
        return text
    
    def _add_emphasis(self, text: str) -> str:
        """添加重音标记"""
        # 简单的重音策略：对关键词进行强调
        emphasis_words = ['重要', '关键', '特别注意', '重要', 'critical', 'important', 'key']
        
        for word in emphasis_words:
            emphasis_level = "strong" if self.settings.emphasis > 1.2 else "moderate"
            text = text.replace(word, f'<emphasis level="{emphasis_level}">{word}</emphasis>')
        
        return text
    
    def _add_breathing_pauses(self, text: str) -> str:
        """添加呼吸停顿"""
        # 在长句中添加呼吸停顿
        sentences = text.split('。')
        for i, sentence in enumerate(sentences):
            if len(sentence) > 50 and i < len(sentences) - 1:
                sentences[i] = sentence + '<break time="0.3s"/>[呼吸声]<break time="0.2s"/>'
        
        return '。'.join(sentences)
    
    def calculate_adjusted_rate(self, base_rate: int, text_length: int) -> int:
        """根据文本长度调整语速"""
        # 长文本适当加快语速，短文本适当放慢
        if text_length > 500:
            adjustment_factor = 1.1
        elif text_length < 100:
            adjustment_factor = 0.9
        else:
            adjustment_factor = 1.0
        
        adjusted_rate = int(base_rate * adjustment_factor)
        return max(50, min(500, adjusted_rate))
    
    def get_gender_adjusted_pitch(self, base_pitch: int) -> int:
        """根据性别因子调整音调"""
        adjusted_pitch = int(base_pitch * self.settings.gender_factor)
        return max(0, min(100, adjusted_pitch))
    
    def create_custom_preset(self, name: str, settings: VoiceSettings) -> bool:
        """创建自定义预设"""
        if self._validate_voice_settings(settings):
            self._presets[name] = settings
            return True
        return False
    
    def _validate_voice_settings(self, settings: VoiceSettings) -> bool:
        """验证语音设置"""
        return (50 <= settings.rate <= 500 and
                0.0 <= settings.volume <= 1.0 and
                0 <= settings.pitch <= 100 and
                0.5 <= settings.emphasis <= 2.0 and
                settings.pause_duration >= 0 and
                0.5 <= settings.gender_factor <= 2.0)
    
    def get_preset_description(self, preset_name: str) -> Optional[str]:
        """获取预设描述"""
        descriptions = {
            'normal': '正常语音，适合日常阅读',
            'slow': '慢速语音，适合学习和详细说明',
            'fast': '快速语音，适合快速浏览',
            'calm': '平静语音，适合放松和冥想',
            'energetic': '活力语音，适合激励和演讲',
            'robot': '机器人语音，科技感强',
            'child': '儿童语音，高音调活泼',
            'elderly': '老年语音，低沉缓慢',
            'news_anchor': '新闻主播语音，清晰正式',
            'storyteller': '故事讲述语音，富有表现力'
        }
        return descriptions.get(preset_name)
    
    def optimize_for_content_type(self, content_type: str) -> str:
        """根据内容类型优化语音设置"""
        content_presets = {
            'news': 'news_anchor',
            'story': 'storyteller',
            'education': 'calm',
            'presentation': 'normal',
            'audiobook': 'slow',
            'announcement': 'energetic'
        }
        
        preset = content_presets.get(content_type, 'normal')
        self.apply_preset(preset)
        return preset
